
package uk.addie.mp3fixer;

import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.AbstractListModel;

public class FileSystemList extends AbstractListModel<String> {
    public static class AlbumList extends FileSystemList {
        private static final long serialVersionUID = 1L;

        public void changeArtist(final String artist) {
            setPath(MP3Fixer.getRoot().resolve(artist));
            listOfFiles = dirsInPath(getPath());
            fireContentsChanged();
        }
    }

    public static class ArtistList extends FileSystemList {
        private static final long serialVersionUID = 1L;

        public ArtistList() {
            super(MP3Fixer.getRoot());
        }
    }

    public static class TrackList extends FileSystemList {
        private static final long serialVersionUID = 1L;

        @Override public void refresh() {
            if (getPath() != null) {
                listOfFiles = FileSystemList.filesInPath(getPath());
            }
            fireContentsChanged();
        }

        public void setAlbum(final String artist, final String album) {
            setPath(MP3Fixer.getRoot().resolve(artist).resolve(album));
            listOfFiles = FileSystemList.filesInPath(getPath());
            super.fireContentsChanged(this, 0, getSize());
        }
    }

    private static final long serialVersionUID = 1L;

    private static List<String> allInPath(final Path path, final boolean isDir) {
        if (path == null || path.toFile().listFiles() == null) {
            return Collections.EMPTY_LIST;
        }
        final List<String> rval = new ArrayList<>();
        for (final File f : path.toFile().listFiles()) {
            if (f.isDirectory() == isDir) {
                rval.add(f.getName());
            }
        }
        Collections.sort(rval);
        return rval;
    }

    protected static List<String> dirsInPath(final Path path) {
        return allInPath(path, true);
    }

    protected static List<String> filesInPath(final Path path) {
        return allInPath(path, false);
    }

    protected List<String> listOfFiles = Collections.EMPTY_LIST;
    private Path           path;

    protected FileSystemList() {
        // no code
    }

    protected FileSystemList(final Path path) {
        this.path = path;
        listOfFiles = FileSystemList.dirsInPath(path);
    }

    public void clear() {
        listOfFiles.clear();
        fireContentsChanged(this, 0, 0);
    }

    protected void fireContentsChanged() {
        super.fireContentsChanged(this, 0, listOfFiles.size());
    }

    @Override public String getElementAt(final int index) {
        return listOfFiles.get(index);
    }

    public Path getPath() {
        return path;
    }

    @Override public int getSize() {
        return listOfFiles.size();
    }

    public void refresh() {
        if (path == null) {
            listOfFiles = Collections.EMPTY_LIST;
        } else {
            listOfFiles = FileSystemList.dirsInPath(path);
        }
        fireContentsChanged();
    }

    public void setPath(final Path path) {
        this.path = path;
        refresh();
    }
}
